<script setup lang="ts">
import Pagination from '@src/components/Pagination.vue'
import { onMounted, onUnmounted, ref } from 'vue'
import { TypePageDTO } from '@src/interfaces/TypePageDTO.ts'
import { TypeBalanceApply } from '@src/interfaces/TypeBalanceApply.ts'
import {
  agreeBalanceApplyApi,
  getClassBalanceApplyListApi,
  refuseBalanceApplyApi,
  revokeBalanceApplyApi,
} from '@src/apis/balanceApply.ts'
import TokenUtil from '@util/TokenUtil.ts'
import useUserStore from '@src/stores/useUserStore.ts'
import { router } from '@util/RouterUtil.ts'
import { ElMessage, FormInstance, FormRules } from 'element-plus'
import { TypeUser } from '@src/interfaces/TypeUser.ts'
import formatDate from '@util/formatDate.ts'
import { EnumBalanceApplyStatus } from '@src/enums/EnumBalanceApplyStatus.ts'
import { storeToRefs } from 'pinia'
import Template from '@src/Template.vue'
import { EnumUserRole } from '@src/enums/EnumUserRole.ts'
import { Picture as IconPicture } from '@element-plus/icons-vue'
import ImagePreview from '@src/components/ImagePreview.vue'
import { getImageUrlByImageName, uploadImageApi } from '@src/apis/imageApi.ts'

const userInfo = storeToRefs(useUserStore()).userInfo

const page = ref<TypePageDTO<TypeBalanceApply & { user: TypeUser }>>({
  current: 1,
  records: [],
  size: 10,
  total: 0,
})

const getClassBalanceApplyList = () => {
  getClassBalanceApplyListApi({
    page: page.value.current,
    size: page.value.size,
  }).then(({ data }) => {
    page.value = data
  })
}

const handlePageChange = (value: number) => {
  page.value.current = value
  getClassBalanceApplyList()
}
const handleSizeChange = (value: number) => {
  page.value.size = value
  getClassBalanceApplyList()
}

onMounted(async () => {
  await TokenUtil.refresh()
  if (!userInfo.value.classId) {
    ElMessage.warning('请先加入班级')
    toClassJoin()
    return
  }

  getClassBalanceApplyList()
})

const toClassJoin = () => {
  router.push('/class/join')
}

/**
 * 同意申请
 */
const agree = (item: TypeBalanceApply) => {
  formData.value = { ...item }
  dialogVisible.value = true
}

/**
 * 拒绝申请
 */
const refuse = (item: TypeBalanceApply) => {
  refuseBalanceApplyApi(item).then(({ message }) => {
    ElMessage.success(message)
    getClassBalanceApplyList()
  })
}

/**
 * 撤回申请
 */
const revoke = (item: TypeBalanceApply) => {
  revokeBalanceApplyApi(item).then(({ message }) => {
    ElMessage.success(message)
    getClassBalanceApplyList()
  })
}

/**预览图片*/
const imagePreviewProps = ref({
  show: false,
  src: '',
  alt: '',
})
onMounted(() => {
  const previewListener = () => {
    const listener = (e: MouseEvent) => {
      const target = e.target as HTMLElement
      if (target.tagName.toLowerCase() !== 'img') return

      const imgEl = target as HTMLImageElement
      imagePreviewProps.value.src = imgEl.src
      imagePreviewProps.value.alt = imgEl.alt
      imagePreviewProps.value.show = true
    }
    window.addEventListener('click', listener)

    return () => {
      window.removeEventListener('click', listener)
    }
  }
  const removePreviewListener = previewListener()
  onUnmounted(() => {
    removePreviewListener()
  })
})

const dialogVisible = ref(false)
/**
 * 同意申请时上传图片的表单
 */
const formData = ref<TypeBalanceApply>({
  amount: 0,
  classId: 0,
  reason: '',
  receiveImageName: '',
  loanImageName: '',
  userId: 0,
})
const formRef = ref<FormInstance>()
const formRules = ref<FormRules<typeof formData>>({
  loanImageName: [
    {
      required: true,
      message: '请上传放款截图',
      trigger: 'blur',
    },
  ],
})
const uploadImage = ({ raw: file }: { raw: File }) => {
  uploadImageApi(file).then(({ data }) => {
    formData.value.loanImageName = data
  })
}
const submitForm = () => {
  formRef.value
    ?.validate((valid) => {
      if (!valid) return
      agreeBalanceApplyApi(formData.value).then(({ message }) => {
        ElMessage.success(message)
        getClassBalanceApplyList()
      })
    })
    .finally(() => {
      dialogVisible.value = false
    })
}
</script>

<template>
  <div>
    <h2><el-text>申请记录</el-text></h2>
    <div class="table-box">
      <el-table :data="page.records" height="750">
        <el-table-column type="expand" label="图片" width="60">
          <template #default="scope">
            <div class="detail-box">
              <div class="detail-item">
                <div class="label"><el-text>收款二维码图片</el-text></div>
                <div class="image">
                  <el-tooltip content="点击预览图片">
                    <el-image
                      :src="getImageUrlByImageName(scope.row.receiveImageName)"
                    >
                      <template #error>
                        <div class="image-slot">
                          <el-icon><icon-picture /></el-icon>
                        </div>
                      </template>
                    </el-image>
                  </el-tooltip>
                </div>
              </div>
              <div class="detail-item">
                <div class="label"><el-text>放款截图</el-text></div>
                <div class="image">
                  <el-tooltip content="点击预览图片">
                    <el-image
                      :src="getImageUrlByImageName(scope.row.loanImageName)"
                    >
                      <template #error>
                        <div class="image-slot">
                          <el-icon><icon-picture /></el-icon>
                        </div>
                      </template>
                    </el-image>
                  </el-tooltip>
                </div>
              </div>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="id" label="申请ID" sortable />
        <el-table-column label="申请人">
          <template #default="scope">
            <el-text>{{ scope.row.user.name }}</el-text>
          </template>
        </el-table-column>
        <el-table-column prop="reason" label="申请原因" />
        <el-table-column prop="amount" label="申请金额" sortable>
          <template #default="scope">
            <el-text type="danger">{{ scope.row.amount }}</el-text>
          </template>
        </el-table-column>
        <el-table-column prop="applyTime" label="申请时间" sortable>
          <template #default="scope">
            <el-text>{{ formatDate(scope.row.applyTime) }}</el-text>
          </template>
        </el-table-column>
        <el-table-column prop="auditTime" label="审核时间">
          <template #default="scope">
            <div v-if="scope.row.status === EnumBalanceApplyStatus.WAITING">
              <el-text type="primary">审核中</el-text>
            </div>
            <div v-else-if="scope.row.status === EnumBalanceApplyStatus.AGREE">
              <el-text type="success">
                {{ formatDate(scope.row.auditTime) }}
              </el-text>
            </div>
            <div v-else-if="scope.row.status === EnumBalanceApplyStatus.REFUSE">
              <el-text type="danger">
                {{ formatDate(scope.row.auditTime) }}
              </el-text>
            </div>
            <div v-else>
              <el-text type="info">已撤回</el-text>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="status" label="状态">
          <template #default="scope">
            <div v-if="scope.row.status === EnumBalanceApplyStatus.WAITING">
              <el-text type="primary">{{ scope.row.status }}</el-text>
            </div>
            <div v-else-if="scope.row.status === EnumBalanceApplyStatus.AGREE">
              <el-text type="success">{{ scope.row.status }}</el-text>
            </div>
            <div v-else-if="scope.row.status === EnumBalanceApplyStatus.REFUSE">
              <el-text type="danger">{{ scope.row.status }}</el-text>
            </div>
            <div v-else>
              <el-text type="info">{{ scope.row.status }}</el-text>
            </div>
          </template>
        </el-table-column>
        <el-table-column prop="beforeClassBalance" label="审核前班费余额">
          <template #default="scope">
            <div v-if="scope.row.status === EnumBalanceApplyStatus.WAITING">
              <el-text type="primary">审核中</el-text>
            </div>
            <div v-else-if="scope.row.status === EnumBalanceApplyStatus.AGREE">
              <el-text type="success">
                {{ scope.row.beforeClassBalance }}
              </el-text>
            </div>
            <div v-else-if="scope.row.status === EnumBalanceApplyStatus.REFUSE">
              <el-text type="danger">申请被拒绝</el-text>
            </div>
            <div v-else>
              <el-text type="info">申请已撤回</el-text>
            </div>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="240" fixed="right">
          <template #default="scope">
            <div class="operation">
              <div v-if="scope.row.status === EnumBalanceApplyStatus.WAITING">
                <span v-if="userInfo.id === scope.row.userId">
                  <el-button type="info" @click="revoke(scope.row)"
                    >撤回</el-button
                  >
                </span>
                <span v-if="userInfo.role === EnumUserRole.CLASS_ADMIN">
                  <el-button type="success" @click="agree(scope.row)"
                    >同意</el-button
                  >
                  <el-button type="danger" @click="refuse(scope.row)"
                    >拒绝</el-button
                  >
                </span>
              </div>
            </div>
          </template>
        </el-table-column>
      </el-table>
    </div>
    <div class="page">
      <Pagination
        :page="page.current"
        :size="page.size"
        :total="page.total"
        @page-change="handlePageChange"
        @size-change="handleSizeChange"
      />
    </div>
    <el-dialog v-model="dialogVisible" title="上传放款截图" width="500">
      <el-form ref="formRef" :model="formData" :rules="formRules">
        <el-form-item prop="loanImageName">
          <div class="upload-box">
            <el-upload
              :auto-upload="false"
              :on-change="uploadImage"
              :show-file-list="false"
              drag
            >
              <el-tooltip content="点击上传放款截图">
                <el-image
                  :src="getImageUrlByImageName(<string>formData.loanImageName)"
                  :alt="formData.loanImageName"
                >
                  <template #error>
                    <div class="image-slot">
                      <el-icon><icon-picture /></el-icon>
                    </div>
                  </template>
                </el-image>
              </el-tooltip>
            </el-upload>
          </div>
        </el-form-item>
        <el-button type="primary" @click="submitForm"> 确认放款 </el-button>
      </el-form>
    </el-dialog>
    <image-preview
      v-model:show="imagePreviewProps.show"
      v-model:src="imagePreviewProps.src"
      v-model:alt="imagePreviewProps.alt"
    />
  </div>
</template>

<style scoped lang="less">
h2 {
  text-align: center;

  .el-text {
    font-size: 2em;
  }
}

.el-table {
  .detail-box {
    display: flex;
    justify-content: space-around;

    .detail-item {
      display: flex;
      flex-direction: column;
      align-items: center;
      border: var(--el-border-color) 1px solid;
      border-radius: var(--el-border-radius-base);
      width: 400px;

      .label {
        text-align: center;
        width: 100%;
        border-bottom: 1px solid var(--el-border-color);

        .el-text {
          font-size: 20px;
        }
      }

      .image {
        .image-slot {
          display: flex;
          justify-content: center;
          align-items: center;
          font-size: 30px;
          min-height: 300px;
        }
      }
    }
  }

  .operation {
    display: flex;
    flex-direction: row;

    .el-button {
      margin: 0 5px;
    }
  }
}

.el-dialog {
  .el-form {
    .upload-box {
      display: flex;
      justify-content: center;
      width: 100%;

      .image-slot {
        display: flex;
        justify-content: center;
        align-items: center;
        font-size: 30px;
        height: 300px;
        width: 450px;
      }
    }
  }

  .el-button {
    width: 100%;
  }
}
</style>
